﻿
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using DotSpatial.Data;
using DotSpatial.Data.Forms;
using DotSpatial.Projections;
using DotSpatial.Serialization;
using DotSpatial.Symbology;
using DotSpatial.Topology;
using Point = System.Drawing.Point;
using SelectionMode = DotSpatial.Symbology.SelectionMode;








namespace FXnaGis
{

    /// <summary>
    /// 这个类包含操作函数，以及图层基础绘制，输入事件的订阅
    /// </summary>
    public partial class FMap : UserControl
    {
        public FMap()
        {
            InitializeComponent();

          

            this.Configure();

        }



        

        #region Private Variables

       

      


   


        MapFunctionService _functionService;

        public MapFunctionService FunctionService
        {
            get { return _functionService; }
           
        }





        private FMapFrame _geoMapFrame;

        public FMapFrame GeoMapFrame
        {
            get { return _geoMapFrame; }
            set { _geoMapFrame = value; }
        }

        private int _isBusyIndex;
        private bool _isResizing;
        

        private Size _oldParentSize;
        private bool _parentFormSizeChanging;

        private IProgressHandler _progressHandler;
        private bool isPanningTemporarily;

      





        #endregion




        private void Configure()
        {

            this.BackColor = Color.White;

            this._geoMapFrame = new FMapFrame(this, new Extent(-180, -90, 180, 90));




            this._functionService = new MapFunctionService(this);


        






            FPanMF pan = new FPanMF(this._geoMapFrame);

          

            FZoomMF zoom = new FZoomMF(this._geoMapFrame);

           


            this._functionService.AddMapFunction(pan);

            this._functionService.AddMapFunction(zoom);


            //比例尺信息

            FScaleMF scale = new FScaleMF(this._geoMapFrame);

            this._functionService.AddMapFunction(scale);


            //标准选择

            FSelectMF select = new FSelectMF(this._geoMapFrame);
            this._functionService.AddMapFunction(select);





            this._geoMapFrame.BufferChanged += new EventHandler<FClipArgs>(_geoMapFrame_BufferChanged);







        }

        void _geoMapFrame_BufferChanged(object sender, FClipArgs e)
        {
            Rectangle view = this._geoMapFrame.View;
            foreach (Rectangle clip in e.ClipRectangles)
            {
                if (clip.IsEmpty == false)
                {
                    Rectangle mapClip = new Rectangle(clip.X - view.X, clip.Y - view.Y, clip.Width, clip.Height);
                    Invalidate(mapClip);
                }
            }
           

        }



      



        #region 订阅各种事件


     
        #endregion


      







   




        #region 控件流程控制
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);


          


            //用于修正视图，主要是前期视图的控件比例不对，所以这里修正一下

            this._geoMapFrame.ResetExtents();


            //控件加载后需要保存的事件

            this.SizeChanged += new EventHandler(FMap_SizeChanged);


            //我们需要同时兼顾父窗体的情况

            if (this.ParentForm!=null)
            {
                this.ParentForm.ResizeEnd += new EventHandler(ParentForm_ResizeEnd);
                
            }


        }

        void ParentForm_ResizeEnd(object sender, EventArgs e)
        {
            //否则会出现比例重置


            this._geoMapFrame.ResetBuffer();


        }



        void FMap_SizeChanged(object sender, EventArgs e)
        {

            //否则会出现比例重置


            this._geoMapFrame.ResetBuffer();
        }


      


        protected override void OnPaintBackground(PaintEventArgs e)
        {

            //去掉背景自动刷新，以减少闪烁，我找你找了好久
            //base.OnPaintBackground(e);
        }


        protected override void OnPaint(PaintEventArgs e)
        {
          

            if (DesignMode)
            {
                return;
            }



            if (_geoMapFrame.IsPanning) return;

            Rectangle clip = e.ClipRectangle;
            if (clip.IsEmpty || _isResizing) clip = ClientRectangle;

            // if the area to paint is too small, there's nothing to paint.
            // Added to fix http://dotspatial.codeplex.com/workitem/320
            if (clip.Width < 1 || clip.Height < 1) return;

            Bitmap stencil = new Bitmap(clip.Width, clip.Height, PixelFormat.Format32bppArgb);


            //主要背景g


            Graphics g = Graphics.FromImage(stencil);
            g.SmoothingMode = SmoothingMode.AntiAlias;


            Brush b = new SolidBrush(BackColor);
            g.FillRectangle(b, new Rectangle(0, 0, stencil.Width, stencil.Height));
            b.Dispose();
            Matrix m = new Matrix();
            m.Translate(-clip.X, -clip.Y);
            g.Transform = m;


            //执行图层的绘制函数

            _geoMapFrame.Draw(new PaintEventArgs(g, e.ClipRectangle));


            FMapArgs ma = new FMapArgs(clip, _geoMapFrame.ViewExtents);

            FMapDrawArgs args = new FMapDrawArgs(g, clip, ma);


            //如果工具类被开启，则绘制工具函数


            this._functionService.Draw(args);


          



            PaintEventArgs pe = new PaintEventArgs(g, e.ClipRectangle);
            base.OnPaint(pe);

            g.Dispose();

            if (_isResizing)
            {
               

            }
            else
            {
                e.Graphics.DrawImageUnscaled(stencil, clip.X, clip.Y);
            }

            stencil.Dispose();
            



        }


        #endregion


        /// <summary>
        /// 强制控件刷新自身一次
        /// 并从新读取buffer内容
        /// </summary>
        public override void Refresh()
        {
           

            _geoMapFrame.Initialize();

            base.Refresh();

          
        }


        public void ZoomToMaxExtent()
        {
            Extent ext = this._geoMapFrame.LayerService.Extent;

            if (ext==null)
            {
                return;
                
            }

            // to prevent exception when zoom to map with one layer with one point
            const double eps = 1e-7;
            if (ext.Width < eps || ext.Height < eps)
            {
                Extent newExtent = new Extent(ext.MinX - eps, ext.MinY - eps, ext.MaxX + eps, ext.MaxY + eps);
               
                _geoMapFrame.ViewExtents = newExtent;
            }
            else
            {
                _geoMapFrame.ViewExtents = ext;
            }

            //最后刷新视图

            this.Invalidate();


        }


        /// <summary>
        /// 缩放到指定图层
        /// </summary>
        /// <param name="layer"></param>

        public void ZoomToLayer(FLayer layer)
        {


            Extent ext = layer.Extent;



            // to prevent exception when zoom to map with one layer with one point
            const double eps = 1e-7;
            if (ext.Width < eps || ext.Height < eps)
            {
                Extent newExtent = new Extent(ext.MinX - eps, ext.MinY - eps, ext.MaxX + eps, ext.MaxY + eps);

                _geoMapFrame.ViewExtents = newExtent;
            }
            else
            {
                _geoMapFrame.ViewExtents = ext;
            }

            //最后刷新视图

            this.Invalidate();

 
        }

    }
}
